/***********************************************************************//***
 * @file        uart_interrupt_test.c
 * @purpose     This example describes how to using UART in interrupt mode
 * @version     2.0
 * @date        21. May. 2010
 * @author      NXP MCU SW Application Team
 *---------------------------------------------------------------------
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 **********************************************************************/
 #include "Uart_Interrupt_g8.h"
 extern LPC_UART_TypeDef *UARTx;
/*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
/*********************************************************************//**
 * @brief       UART0 interrupt handler sub-routine
 * @param[in]   None
 * @return      None
 **********************************************************************/
void UART0_IRQHandler(void)
{
    		/* Temporarily lock out UART receive interrupts during this
       read so the UART receive interrupt won't cause problems
       with the index values */
    UART_IntConfig(UARTx, UART_INTCFG_RBR, DISABLE);
            UART_IntReceive();
			/* Re-enable UART interrupts */
    UART_IntConfig(UARTx, UART_INTCFG_RBR, ENABLE);
   
}
 
/********************************************************************//**
 * @brief       UART receive function (ring buffer used)
 * @param[in]   None
 * @return      None
 *********************************************************************/
void UART_IntReceive(void)
{
    uint8_t tmpc;
    uint32_t rLen;
	flagJ = 0;
	flagZ=0;
 
    	//flagJ = UART_ReceiveByte(UARTx);
        // Call UART read function in UART driver
        rLen = UART_Receive(UARTx, &tmpc, 1, NONE_BLOCKING);
        // If data received
        if (rLen){
            /* Check if buffer is more space
             * If no more space, remaining character will be trimmed out
             */
            
                rb.rx[0] = tmpc;
				flagZ = &tmpc;
				flagJ = tmpc;
				
            }
			
        
	
    
}
 
/********************************************************************//**
 * @brief       UART transmit function (ring buffer used)
 * @param[in]   None
 * @return      None
 *********************************************************************/
void UART_IntTransmit(void)
{
    // Disable THRE interrupt
    UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0, UART_INTCFG_THRE, DISABLE);
 
    /* Wait for FIFO buffer empty, transfer UART_TX_FIFO_SIZE bytes
     * of data or break whenever ring buffers are empty */
    /* Wait until THR empty */
    while (UART_CheckBusy((LPC_UART_TypeDef *)LPC_UART0) == SET);
 
    while (!__BUF_IS_EMPTY(rb.tx_head,rb.tx_tail))
    {
        /* Move a piece of data into the transmit FIFO */
        if (UART_Send((LPC_UART_TypeDef *)LPC_UART0, (uint8_t *)&rb.tx[rb.tx_tail], 1, NONE_BLOCKING)){
        /* Update transmit ring FIFO tail pointer */
        __BUF_INCR(rb.tx_tail);
        } else {
            break;
        }
    }
 
    /* If there is no more data to send, disable the transmit
       interrupt - else enable it or keep it enabled */
    if (__BUF_IS_EMPTY(rb.tx_head, rb.tx_tail)) {
        UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0, UART_INTCFG_THRE, DISABLE);
        // Reset Tx Interrupt state
        TxIntStat = RESET;
    }
    else{
        // Set Tx Interrupt state
        TxIntStat = SET;
        UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0, UART_INTCFG_THRE, ENABLE);
    }
}
 
 
/*********************************************************************//**
 * @brief       UART Line Status Error
 * @param[in]   bLSErrType  UART Line Status Error Type
 * @return      None
 **********************************************************************/
void UART_IntErr(uint8_t bLSErrType)
{
    uint8_t test;
    // Loop forever
    while (1){
        // For testing purpose
        test = bLSErrType;
		break;
    }
}
 
/*-------------------------PRIVATE FUNCTIONS------------------------------*/
/*********************************************************************//**
 * @brief       UART transmit function for interrupt mode (using ring buffers)
 * @param[in]   UARTPort    Selected UART peripheral used to send data,
 *              should be UART0
 * @param[out]  txbuf Pointer to Transmit buffer
 * @param[in]   buflen Length of Transmit buffer
 * @return      Number of bytes actually sent to the ring buffer
 **********************************************************************/
uint32_t UARTSend(LPC_UART_TypeDef *UARTPort, uint8_t *txbuf, uint8_t buflen)
{
    uint8_t *data = (uint8_t *) txbuf;
    uint32_t bytes = 0;
	uint8_t len = buflen;
 
    /* Temporarily lock out UART transmit interrupts during this
       read so the UART transmit interrupt won't cause problems
       with the index values */
    UART_IntConfig(UARTPort, UART_INTCFG_THRE, DISABLE);
 
    /* Loop until transmit run buffer is full or until n_bytes
       expires */
    while ((len != 0)) /*&& (!__BUF_IS_FULL(rb.tx_head, rb.tx_tail))) */
    {
        /* Write data from buffer into ring buffer */
        UART_SendByte((LPC_UART_TypeDef *)LPC_UART0,data[bytes]); 
        //data++;
 
        /* Increment head pointer */
        __BUF_INCR(rb.tx_head);
 
        /* Increment data count and decrement buffer size count */
        bytes++;
        buflen--;
    }
 
    /*
     * Check if current Tx interrupt enable is reset,
     * that means the Tx interrupt must be re-enabled
     * due to call UART_IntTransmit() function to trigger
     * this interrupt type
     */
   
    /*
     * Otherwise, re-enables Tx Interrupt
     */
    
        UART_IntConfig(UARTPort, UART_INTCFG_THRE, ENABLE);
    
 
    return bytes;
}
 
 
/*********************************************************************//**
 * @brief       UART read function for interrupt mode (using ring buffers)
 * @param[in]   UARTPort    Selected UART peripheral used to send data,
 *              should be UART0
 * @param[out]  rxbuf Pointer to Received buffer
 * @param[in]   buflen Length of Received buffer
 * @return      Number of bytes actually read from the ring buffer
 **********************************************************************/
uint32_t UARTReceive(LPC_UART_TypeDef *UARTPort, uint8_t *rxbuf, uint8_t buflen)
{
    uint8_t *data = (uint8_t *) rxbuf;
    uint32_t bytes = 0;
 
    /* Temporarily lock out UART receive interrupts during this
       read so the UART receive interrupt won't cause problems
       with the index values */
    UART_IntConfig(UARTPort, UART_INTCFG_RBR, DISABLE);
 
    /* Loop until receive buffer ring is empty or
        until max_bytes expires */
    while ((buflen > 0) && (!(__BUF_IS_EMPTY(rb.rx_head, rb.rx_tail))))
    {
        /* Read data from ring buffer into user buffer */
        *data = rb.rx[rb.rx_tail];
        data++;
 
        /* Update tail pointer */
        __BUF_INCR(rb.rx_tail);
 
        /* Increment data count and decrement buffer size count */
        bytes++;
        buflen--;
    }
 
    /* Re-enable UART interrupts */
    UART_IntConfig(UARTPort, UART_INTCFG_RBR, ENABLE);
 
    return bytes;
}
 
/*********************************************************************//**
 * @brief   Print Welcome Screen Menu subroutine
 * @param   None
 * @return  None
 **********************************************************************/
void print_menu(void)
{
    uint32_t tmp, tmp2;
    uint8_t *pDat;
 
    tmp = sizeof(menu1);
    tmp2 = 0;
    pDat = (uint8_t *)&menu1[0];
    while(tmp) {
        tmp2 = UARTSend((LPC_UART_TypeDef *)LPC_UART0, pDat, tmp);
        pDat += tmp2;
        tmp -= tmp2;
    }
 
    tmp = sizeof(menu2);
    tmp2 = 0;
    pDat = (uint8_t *)&menu2[0];
    while(tmp) {
        tmp2 = UARTSend((LPC_UART_TypeDef *)LPC_UART0, pDat, tmp);
        pDat += tmp2;
        tmp -= tmp2;
    }
}
 
/*-------------------------MAIN FUNCTION------------------------------*/
/*********************************************************************//**
 * @brief       c_entry: Main UART program body
 * @param[in]   None
 * @return      int
 **********************************************************************/
//int c_entry(void)
//{
//    // UART Configuration structure variable
//    UART_CFG_Type UARTConfigStruct;
//    // UART FIFO configuration Struct variable
//    UART_FIFO_CFG_Type UARTFIFOConfigStruct;
//    // Pin configuration for UART0
//    PINSEL_CFG_Type PinCfg;
// 
//    uint32_t idx, len;
//    __IO FlagStatus exitflag;
//    uint8_t buffer[10];
// 
//    /*
//     * Initialize UART0 pin connect
//     */
//    PinCfg.Funcnum = 1;
//    PinCfg.OpenDrain = 0;
//    PinCfg.Pinmode = 0;
//    PinCfg.Pinnum = 2;
//    PinCfg.Portnum = 0;
//    PINSEL_ConfigPin(&PinCfg);
//    PinCfg.Pinnum = 3;
//    PINSEL_ConfigPin(&PinCfg);
// 
// 
//    /* Initialize UART Configuration parameter structure to default state:
//     * Baudrate = 9600bps
//     * 8 data bit
//     * 1 Stop bit
//     * None parity
//     */
//    UART_ConfigStructInit(&UARTConfigStruct);
// 
//    // Initialize UART0 peripheral with given to corresponding parameter
//    UART_Init((LPC_UART_TypeDef *)LPC_UART0, &UARTConfigStruct);
// 
// 
//    /* Initialize FIFOConfigStruct to default state:
//     *              - FIFO_DMAMode = DISABLE
//     *              - FIFO_Level = UART_FIFO_TRGLEV0
//     *              - FIFO_ResetRxBuf = ENABLE
//     *              - FIFO_ResetTxBuf = ENABLE
//     *              - FIFO_State = ENABLE
//     */
//    UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
// 
//    // Initialize FIFO for UART0 peripheral
//    UART_FIFOConfig((LPC_UART_TypeDef *)LPC_UART0, &UARTFIFOConfigStruct);
// 
// 
//    // Enable UART Transmit
//    UART_TxCmd((LPC_UART_TypeDef *)LPC_UART0, ENABLE);
// 
//    /* Enable UART Rx interrupt */
//    UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0, UART_INTCFG_RBR, ENABLE);
//    /* Enable UART line status interrupt */
//    UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0, UART_INTCFG_RLS, ENABLE);
//    /*
//     * Do not enable transmit interrupt here, since it is handled by
//     * UART_Send() function, just to reset Tx Interrupt state for the
//     * first time
//     */
//    TxIntStat = RESET;
// 
//    // Reset ring buf head and tail idx
//    __BUF_RESET(rb.rx_head);
//    __BUF_RESET(rb.rx_tail);
//    __BUF_RESET(rb.tx_head);
//    __BUF_RESET(rb.tx_tail);
// 
//    /* preemption = 1, sub-priority = 1 */
//    NVIC_SetPriority(UART0_IRQn, ((0x01<<3)|0x01));
//    /* Enable Interrupt for UART0 channel */
//    NVIC_EnableIRQ(UART0_IRQn);
// 
// 
//    // print welcome screen
//    print_menu();
// 
//    // reset exit flag
//    exitflag = RESET;
// 
//    /* Read some data from the buffer */
////    while (exitflag == RESET)
////    {
////       len = 0;
////        while (len == 0)
////        {
////            len = UARTReceive((LPC_UART_TypeDef *)LPC_UART0, buffer, sizeof(buffer));
////        }
//// 
////        /* Got some data */
////        idx = 0;
////        while (idx < len)
////        {
////            if (buffer[idx] == 27)
////            {
////                /* ESC key, set exit flag */
////                UARTSend((LPC_UART_TypeDef *)LPC_UART0, menu3, sizeof(menu3));
////                exitflag = SET;
////            }
////            else if (buffer[idx] == 'r')
////            {
////                print_menu();
////            }
////            else
////            {
////                /* Echo it back */
////                UARTSend((LPC_UART_TypeDef *)LPC_UART0, &buffer[idx], 1);
////            }
////            idx++;
////        }
////    }
// 
////    // wait for current transmission complete - THR must be empty
////    while (UART_CheckBusy((LPC_UART_TypeDef *)LPC_UART0));
//// 
////    // DeInitialize UART0 peripheral
////    UART_DeInit((LPC_UART_TypeDef *)LPC_UART0);
//// 
////    /* Loop forever */
////    while(1);
////    return 1;
//}
// 
///* With ARM and GHS toolsets, the entry point is main() - this will
//   allow the linker to generate wrapper code to setup stacks, allocate
//   heap area, and initialize and copy code and data segments. For GNU
//   toolsets, the entry point is through __start() in the crt0_gnu.asm
//   file, and that startup code will setup stacks and data */
//int main(void)
//{
//    return c_entry();
//}
// 
#ifdef  DEBUG
/*******************************************************************************
* @brief        Reports the name of the source file and the source line number
*               where the CHECK_PARAM error has occurred.
* @param[in]    file Pointer to the source file name
* @param[in]    line assert_param error line source number
* @return       None
*******************************************************************************/
void check_failed(uint8_t *file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
    /* Infinite loop */
    while(1);
}
#endif
 
/*
 * @}
 */